package plugins

import (
	"context"
	"gitee.com/go-caipu-team/go-caipu-plugin-sdk/backend"
	"go-caipu/pkg/plugins/backendplugin"
	"time"
)

// Store is the publicly accessible storage for plugins.
type Store interface {
	// Plugin finds a plugin by its ID.
	Plugin(ctx context.Context, pluginID string) (PluginDTO, bool)
	// Plugins returns plugins by their requested type.
	Plugins(ctx context.Context, pluginTypes ...Type) []PluginDTO
}
type Installer interface {
	//Add adds a new plugin.
	Add(ctx context.Context, pluginID, version string, opts AddOpts) error
	Remove(ctx context.Context, pluginID string) error
}
type CompatOpts struct {
	CaiPuVersion string
	OS           string
	Arch         string
}

type FileStore interface {
	// File retrieves a plugin file.
	File(ctx context.Context, pluginID, pluginVersion, filename string) (*File, error)
}

type File struct {
	Content []byte
	ModTime time.Time
}

type AddOpts struct {
	caiPuVersion string

	os   string
	arch string

	url string
}

func (co AddOpts) CaiPuVersion() string {
	return co.caiPuVersion
}

func (co AddOpts) OS() string {
	return co.os
}

func (co AddOpts) Arch() string {
	return co.arch
}

func (co AddOpts) URL() string {
	return co.url
}

func NewAddOpts(version, os, arch, url string) AddOpts {
	return AddOpts{caiPuVersion: version, arch: arch, os: os, url: url}
}

// Client is used to communicate with backend plugin implementations.
type Client interface {
	backend.QueryDataHandler
	backend.CheckHealthHandler
	backend.StreamHandler
	backend.CallResourceHandler
	backend.CollectMetricsHandler
}

// ClientMiddleware is an interface representing the ability to create a middleware
// that implements the Client interface.
type ClientMiddleware interface {
	// CreateClientMiddleware creates a new client middleware.
	CreateClientMiddleware(next Client) Client
}

// The ClientMiddlewareFunc type is an adapter to allow the use of ordinary
// functions as ClientMiddleware's. If f is a function with the appropriate
// signature, ClientMiddlewareFunc(f) is a ClientMiddleware that calls f.
type ClientMiddlewareFunc func(next Client) Client

// CreateClientMiddleware implements the ClientMiddleware interface.
func (fn ClientMiddlewareFunc) CreateClientMiddleware(next Client) Client {
	return fn(next)
}

// BackendFactoryProvider provides a backend factory for a provided plugin.
type BackendFactoryProvider interface {
	BackendFactory(ctx context.Context, p *Plugin) backendplugin.PluginFactoryFunc
}
